package com.samsung.sbackup;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;

import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.samsung.adapter.AppsAdapter;

public class TabInstalledApps extends Fragment {

	ListView lvApps;
	Button btnBackup;
	AppsAdapter adapter;
	SparseArray<Drawable> hashMapIcon;
	SparseArray<String> hashMapName;
	SharedPreferences sharedPref;
	ArrayList<ApplicationInfo> appsList;
	boolean isCheckedAll;
	boolean loadFinised;


	public TabInstalledApps() {
		hashMapIcon = new SparseArray<Drawable>();
		hashMapName = new SparseArray<String>();
		setHasOptionsMenu(true);
		isCheckedAll = false;
		loadFinised = false;
	}


	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.tab_installed_apps, null);

		sharedPref = PreferenceManager
				.getDefaultSharedPreferences(getActivity());

		// get all application infos
		ArrayList<ApplicationInfo> infos = (ArrayList<ApplicationInfo>) getActivity()
				.getPackageManager().getInstalledApplications(
						PackageManager.GET_META_DATA);
		// filter to get the downloaded apps (not system apps)
		appsList = new ArrayList<ApplicationInfo>();
		for (ApplicationInfo applicationInfo : infos) {
			if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0)
				appsList.add(applicationInfo);
		}

		lvApps = (ListView) view.findViewById(R.id.tab_installed_apps_listview);
		btnBackup = (Button) view.findViewById(R.id.tab_installed_apps_btnBackup);
		
		lvApps.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				adapter.getCheckedItems()[arg2] = !adapter.getCheckedItems()[arg2];
				adapter.notifyDataSetChanged();
			}
			
		});

		new LoadImageTask().execute();

		btnBackup.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new BackupApps().execute();
			}
		});

		return view;
	}

	public class BackupApps extends AsyncTask<Void, Integer, String> {
		ProgressDialog progressDialog;
		ArrayList<ApplicationInfo> selectedItems;
		boolean isError;
		String errorMessage;

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			isError = false;
			errorMessage = "No errors";
			progressDialog = new ProgressDialog(getActivity());
			progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			selectedItems = adapter.getSelectedItems();
			progressDialog.setMax(selectedItems.size());
			progressDialog.setTitle("Backing up...");
			progressDialog.setCancelable(false);
			if (selectedItems.size() != 0)
				progressDialog.show();
		}

		@Override
		protected String doInBackground(Void... params) {
			int count = 0;
			for (ApplicationInfo item : selectedItems) {
				try {
					File f1 = new File(item.publicSourceDir);

					String path = sharedPref.getString(
							FragmentSettingsPreference.BACKUP_PATH, "/");

					File f2 = new File(path + "/" + "app");
					f2.mkdirs();
					f2 = new File(f2.getPath() + "/"
							+ item.loadLabel(getActivity().getPackageManager())
							+ ".apk");
					f2.createNewFile();
					InputStream in = new FileInputStream(f1);

					OutputStream out = new FileOutputStream(f2);

					byte[] buf = new byte[1024];
					int len;
					while ((len = in.read(buf)) > 0) {
						out.write(buf, 0, len);
					}
					in.close();
					out.close();
					System.out.println("File copied.");
				} catch (FileNotFoundException ex) {
					ex.printStackTrace();
					isError = true;
					errorMessage = "Error" + ex.toString();
				} catch (IOException e) {
					e.printStackTrace();
					isError = true;
					errorMessage = "Error" + e.toString();
				}
				count++;
				publishProgress(count);
			}

			if (selectedItems.size() != 0)
				return "Done backing up applications";
			else
				return "Please choose apps to backup";
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			progressDialog.setProgress(values[0]);
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			progressDialog.dismiss();
			if (isError)
				Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_SHORT)
						.show();
			else
				Toast.makeText(getActivity(), result, Toast.LENGTH_SHORT)
						.show();
		}
	}

	public class LoadImageTask extends AsyncTask<Void, Void, String> {

		ProgressDialog progressDialog;
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			progressDialog = new ProgressDialog(getActivity());
			progressDialog.setMessage("Loading applications..."); 
			progressDialog.setCancelable(false);
			progressDialog.show();
		}

		@Override
		protected String doInBackground(Void... params) {
			for (int i = 0; i < appsList.size(); i++) {
				hashMapIcon.put(
						i,
						appsList.get(i).loadIcon(
								getActivity().getPackageManager()));
				hashMapName.put(
						i,
						appsList.get(i)
								.loadLabel(getActivity().getPackageManager())
								.toString());
			}
			return "Done";
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			progressDialog.dismiss();
			adapter = new AppsAdapter(getActivity().getApplicationContext(),
					appsList, R.layout.app_item, hashMapIcon, hashMapName, null);
			lvApps.setAdapter(adapter);
			loadFinised = true;
		}
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		super.onCreateOptionsMenu(menu, inflater);
		inflater.inflate(R.menu.apps_backup, menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == R.id.apps_backup_select_all && loadFinised) {
			if (!isCheckedAll) {
				boolean[] checkItems = adapter.getCheckedItems();
				for (int i = 0; i < checkItems.length; i++) {
					checkItems[i] = true;
				}
				adapter.setCheckedItems(checkItems);
				isCheckedAll = true;
			} else {
				boolean[] checkItems = adapter.getCheckedItems();
				for (int i = 0; i < checkItems.length; i++) {
					checkItems[i] = false;
				}
				adapter.setCheckedItems(checkItems);
				isCheckedAll = false;
			}
		}

		return super.onOptionsItemSelected(item);
	}
}
